﻿Friend Class ScanFolder_IndividualFiles
    Friend Shared Sub Scan(ByVal tracker As ScanTracker)
        If Not IO.Directory.Exists(tracker.CurrentPath) Then Return

        tracker.ValidPaths.Add(tracker.CurrentPath, Nothing)

        Dim aFileinfos As Generic.Dictionary(Of String, IO.FileInfo)
        aFileinfos = ScanFolder_Common.GetAllFileInfosRecursive(tracker.CurrentPath)

        Dim aSharedFiles As Generic.List(Of Entities.SharedItemFile)
        aSharedFiles = DataStore.SharedItemsFiles.GetAllBySourceWatchFolderId(tracker.Share.Id)

        'check all existing items
        For Each clsFile As Entities.SharedItemFile In aSharedFiles
            Dim strKey As String = IO.Path.Combine(clsFile.Directory, clsFile.FileName).ToLower
            If aFileinfos.ContainsKey(strKey) Then
                'file still exists, make sure it has not changed
                Dim clsItem As Entities.SharedItem = Nothing
                Using t As New DataStore.TransactionScope
                    If ScanFolder_Common.UpdateSharedFileIfChanged(aFileinfos(strKey), clsFile, t) Then
                        clsitem = DataStore.SharedItems.GetById(clsFile.SharedItemId)
                        Dim clsMI As Entities.MediaInfo = ScanFolder_Common.CreateMediaInfoEx(clsItem)
                        If clsMI IsNot Nothing Then
                            clsMI.SharedItemId = clsItem.Id
                            DataStore.MediaInfo.Save(clsMI, t)
                            clsItem.HasMediaInfo = True
                            DataStore.SharedItems.Save(clsItem, t)
                        End If
                    End If
                    t.Complete()
                End Using
                If clsItem IsNot Nothing Then
                    Manager.OnLogEvent(String.Format("Updated item {0}", clsItem.Name))
                    Manager.OnSharedItemUpdated(clsItem)
                End If
                'remove fileinfo from list
                aFileinfos.Remove(strKey)
            Else
                'file no longer exist, remove shared item
                Dim clsItem As Entities.SharedItem = DataStore.SharedItems.GetById(clsFile.SharedItemId)
                Using t As New DataStore.TransactionScope
                    DataStore.SharedItems.Delete(clsItem, t)
                    t.Complete()
                End Using
                Manager.OnLogEvent(String.Format("Deleted shared item {0}", clsItem.Name))
                Manager.OnSharedItemDeleted(clsItem)
            End If
        Next

        'now, add all files that did not have a corresponding shareditemfile
        For Each clsFI As IO.FileInfo In aFileinfos.Values
            Dim clsItem As New Entities.SharedItem
            clsItem.Added = Now.ToUniversalTime
            clsItem.Directory = clsFI.DirectoryName
            clsItem.GroupMode = tracker.Share.GroupMode
            clsItem.ItemType = tracker.Share.ItemTypes
            clsItem.LastChanged = clsFI.LastWriteTimeUtc
            clsItem.Name = IO.Path.GetFileName(clsFI.FullName)
            clsItem.SourceWatchFolderId = tracker.Share.Id
            clsItem.UniqueId = Utils.Misc.GenerateUniqueId
            clsItem.TotalFiles = 1
            clsItem.TotalSize = clsFI.Length

            Dim clsFile As Entities.SharedItemFile
            clsFile = ScanFolder_Common.CreateSharedItemFile(clsFI)

            Dim clsMI As Entities.MediaInfo = ScanFolder_Common.CreateMediaInfoEx(clsItem)

            Using t As New DataStore.TransactionScope()
                DataStore.SharedItems.Save(clsItem, t)

                clsFile.SharedItemId = clsItem.Id
                DataStore.SharedItemsFiles.Save(clsFile, t)

                If clsMI IsNot Nothing Then
                    clsMI.SharedItemId = clsItem.Id
                    DataStore.MediaInfo.Save(clsMI, t)
                    clsItem.HasMediaInfo = True
                    DataStore.SharedItems.Save(clsItem)
                End If

                t.Complete()
            End Using

            Manager.OnSharedItemCreated(clsItem)
        Next
        
    End Sub

    Private Shared Function UpdateFiles(ByVal tracker As ScanTracker, ByVal item As Entities.SharedItem, ByVal transactionScope As DataStore.TransactionScope) As Boolean
        Dim aFilesInfos As Generic.Dictionary(Of String, IO.FileInfo)
        aFilesInfos = ScanFolder_Common.GetAllFileInfosRecursive(item.Directory)

        Dim aFiles As Generic.List(Of Entities.SharedItemFile)
        aFiles = DataStore.SharedItemsFiles.GetAllBySharedItemId(item.Id)

        Dim blnChanged As Boolean = False

        Dim aSaved As New Generic.Dictionary(Of String, String)
        For Each clsFile As Entities.SharedItemFile In aFiles
            Dim strFileName As String = IO.Path.Combine(clsFile.Directory, clsFile.FileName).ToLower
            If aFilesInfos.ContainsKey(strFileName) Then
                aSaved.Add(strFileName, Nothing)
                Dim clsFI As IO.FileInfo = aFilesInfos(strFileName)
                blnChanged = blnChanged Or ScanFolder_Common.UpdateSharedFileIfChanged(clsFI, clsFile, transactionScope)
            Else
                DataStore.SharedItemsFiles.SetFileAsOrphan(clsFile, transactionScope)
                blnChanged = True
            End If
        Next
        Dim iTotalFiles As Short = 0
        Dim lTotalSize As Long = 0
        Dim dtLastChange As Date = Date.MinValue
        For Each clsFI As IO.FileInfo In aFilesInfos.Values
            iTotalFiles += CShort(1)
            lTotalSize += clsFI.Length
            If clsFI.LastWriteTimeUtc > dtLastChange Then dtLastChange = clsFI.LastWriteTimeUtc
            If Not aSaved.ContainsKey(clsFI.FullName.ToLower) Then
                Dim clsFile As Entities.SharedItemFile
                clsFile = ScanFolder_Common.CreateSharedItemFile(clsFI)
                clsFile.SharedItemId = item.Id
                DataStore.SharedItemsFiles.Save(clsFile)
                blnChanged = True
            End If
        Next
        If item.TotalFiles <> iTotalFiles Then
            blnChanged = True
            item.TotalFiles = iTotalFiles
        End If
        If item.TotalSize <> lTotalSize Then
            blnChanged = True
            item.TotalSize = lTotalSize
        End If
        If Math.Abs(dtLastChange.Subtract(item.LastChanged).TotalSeconds) > 1 Then
            blnChanged = True
            item.LastChanged = dtLastChange
        End If
        Return blnChanged
    End Function


End Class
